/**
 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/vm_sockets.h>
#include <string.h>
#include <glib.h>
#include <errno.h>

#define SERVER_DATA_LEN         8192
#define DEFAULT_CLIENT_CID      2

int g_count = 0;
static void vsock_send(int fd)
{
    char buf[256] = "hello";
    int rs = 1;
    int num = 0;

    char *recvs = g_malloc0(SERVER_DATA_LEN);
    int len;
    len = send(fd, buf, strlen(buf) + 1, 0);
    if (len < 0) {
        perror("send");
        goto free;
    }
    while (rs) {
        int buflen = recv(fd, recvs, SERVER_DATA_LEN, 0);
        if (buflen < 0) {
            perror("recv");
            break;
        } else if (buflen == 0) {
            /* remote socket is closed */
            rs = 0;
        }
        num++;
        printf("[%d] recv data len = [%d]\n", num, buflen);

        memset(recvs, 0, SERVER_DATA_LEN);
    }
free:
    g_free(recvs);
    return;
}

int vsock_connect(int cid, int port)
{
    int fd;
    struct sockaddr_vm sa = { .svm_family = AF_VSOCK, };

    sa.svm_cid = cid;
    sa.svm_port = port;

    fd = socket(AF_VSOCK, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("socket");
        return -1;
    }

    printf("fd = %d\n", fd);

    if (connect(fd, (struct sockaddr*) &sa, sizeof(sa)) != 0) {
        perror("connect fail");
        close(fd);
        return -1;
    }
    vsock_send(fd);
    close(fd);
    return 0;
}

int main(int argc, char *argv[])
{
    int port = atoi(argv[1]);
    printf("port = %d\n", port);
    return vsock_connect(DEFAULT_CLIENT_CID, port);
}
